package cii_lib;

import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import componentEnhancement.ComponentContent;

public class CCII_COMPONENT extends CCII_TABLE_INDEX implements ComponentContent {
	
	
	private static final Logger log = LoggerFactory.getLogger(CCII_COMPONENT.class);
	 //TODO To jest do generacji !
	
	 /**
	 * Structure to agregate interfaces of this component
	 */
	private Vector<CCII_ACCESS_INTERF> interfaces = new Vector<CCII_ACCESS_INTERF>();
	
	  /**
	 * Structure to agregate parameters of this component
	 */
	private Vector<CCII_ACCESS_PARAM> params = new Vector<CCII_ACCESS_PARAM>();
	  /**
	 * Structure to agregate subcomponents of this component
	 */
	private Vector<CCII_COMPONENT> children = new Vector<CCII_COMPONENT>();
	  //TODO
	
	/**
	* Parent of this. 
 	*/
	private CCII_COMPONENT _parent;
  
  //WORKAROUND
  public CCII_COMPONENT(CCII_TABLE_INDEX itab, int index, CCII_COMPONENT parent) {
    super(itab,1);
    if (parent!=null) parent.insertChild(this);
    log.debug("creating component name: "+ GetItem().Name+" "+GetItem().CompID+" "+GetItem().ParIntVal);
    _parent=parent;
    if (
	GetItem().CompID!=GetCompID()
	|| GetItem().Name==null || GetItem().Type!=CIIlib.TABLE_TYPE.COMP
	|| GetItem().Access!=CIIlib.TABLE_ACCESS.NA || GetItem().Repeat<0 || GetItem().Address!=-1
	|| GetItem().Repeat==0 && (GetItem().Width!=-1 || GetItem().Number!=-1)
	|| GetItem().Repeat>0 && (GetItem().Width<1 || GetItem().Number<1 || GetItem().Position!=index)//FIXME dlaczego position 
	|| GetItem().ParIntVal<-1 || GetItem().ParStrVal==null
      )
      try {
	throw new CiiLibException("CCII_COMPONENT",CiiLibException.MSG.TABLE_ERROR);
      } catch (CiiLibException e) {log.error("", e);}
  }
  
  //
  
  public CCII_COMPONENT(CCII_TABLE_INDEX itab, int index, CCII_COMPONENT parent,
		  Vector<CCII_ACCESS_INTERF> interfaces,Vector<CCII_ACCESS_PARAM> params) {
    super(itab,1);
    if (parent!=null) parent.insertChild(this);
    log.debug("creating component name: "+ GetItem().Name+" "+GetItem().CompID+" "+GetItem().ParIntVal);
    setInterfaces(interfaces);
    setParams(params);
    _parent=parent;
    if (
	GetItem().CompID!=GetCompID()
	|| GetItem().Name==null || GetItem().Type!=CIIlib.TABLE_TYPE.COMP
	|| GetItem().Access!=CIIlib.TABLE_ACCESS.NA || GetItem().Repeat<0 || GetItem().Address!=-1
	|| GetItem().Repeat==0 && (GetItem().Width!=-1 || GetItem().Number!=-1)
	|| GetItem().Repeat>0 && (GetItem().Width<1 || GetItem().Number<1 || GetItem().Position!=index)//FIXME dlaczego position 
	|| GetItem().ParIntVal<-1 || GetItem().ParStrVal==null
      )
      try {
	throw new CiiLibException("CCII_COMPONENT",CiiLibException.MSG.TABLE_ERROR);
      } catch (CiiLibException e) {log.error("", e);}
  }
  public boolean Exist() {return((GetItem()==null || GetItem().Repeat==0)?false:true);};
  public CCII_COMPONENT Parent() {return(_parent);};
  public int ParentID() {return(GetItem().ParIntVal);};
  public String Type()  {return(GetItem().ParStrVal);};
  public String Name()  {return(GetItem().Name);};
  public String PathName()  {return(_parent==null?"":CIIlib.PathCompName(Parent())+"."+Name()+
		  "["+Index()+"]");};
  public int DataSize() {return(GetItem().Width);};
  public int AddrSize() {return(GetItem().Number);};
  public int Number()   {return(GetItem().Repeat);};
  public int Index()    {return(GetItem().Position);}
/* (non-Javadoc)
 * @see componentEnhancement.ComponentContent#getInterfaces()
 */
  public Vector<CCII_ACCESS_INTERF> getInterfaces() {
		return interfaces;
	}
	public void setInterfaces(Vector<CCII_ACCESS_INTERF> interfaces) {
		this.interfaces = interfaces;
	}
	public CCII_ACCESS_INTERF getInterfaceByName(String name) {
		for (CCII_ACCESS_INTERF i:interfaces) {
			if (i.Name().equals(name)) 
				return i;
		}
		return null;
	}
	
	public Vector<CCII_ACCESS_PARAM> getParams() {
		return params;
	}
	public CCII_ACCESS_PARAM getParamByName(String name) {
		CCII_ACCESS_PARAM param=null;
		for (CCII_ACCESS_PARAM p:params) {
			if (p.Name().equals(name))
			return p;
		}
		return param;
	}
	
	public void setParams(Vector<CCII_ACCESS_PARAM> params) {
		this.params = params;
	};
	public void insertChild(CCII_COMPONENT child) {
//		log.debug("jestem dziecko"); //FIXME
		children.add(child);
	}
	public Vector<CCII_COMPONENT> getChildren() {
		return children;
	}

	@Override
	public String toString() {
		return super.toString();
	}
	
};
